/** \file FilterCompressor.h
    \author belot.nicolas
    Handle compression
*/
/**
*/

#ifndef FILTERCOMPRESSOR_H
#define FILTERCOMPRESSOR_H 1

#include "Filter.h"
#include <vector>
#include <cmath>
using namespace std;
namespace libtrckr {
class FilterCompressor : public Filter {
	/** \class libtrckr::FilterCompressor
	    \brief Handle compression
		HAndle compression on a stream
		
	     \note compressor
Cas besier

Besier :
	Resolution d'un polynome de degré 2 \n
	\f$ delta =  4. \times (x_1-x_0)^2 - 4. \times (x_0 - 2. \times x_1 + x_2) \times (x_0 - x)\f$ \n
		\f$ t_1 =  -2.0 \times (x_1-x_0) - \sqrt{delta}\f$ \n
		\f$ t_2 = -2.0 \times (x_1-x_0) + \sqrt{delta}\f$ \n
	sauf! si \f$ x1-x0 = x2-x1 \f$ dans ce cas le polynome n'as aucune solution.
	en effet \f$ (x_0 - 2. \times x_1 + x_2) = 0 \f$ donc t est indépendant de x.
	la résolution passe donc par \n
		\f$ \frac{x - x0}{x2 - x0} \f$ \n

Cas quadratic spline interpolation 
 \f$ S(x) = y_i + z_i(x-x_i) + \frac{(z_{i+1} - z_i)(x-x_i)^2 }{2(x_{i+1} -x_i)} \f$
avec \f$ z_{i+1}=-z_1 +\frac{2(y_{i+1} - y_i)}{(x_{i+1}-x_i)} \f$
   	*/

	public:
	enum impulse_res_t {NORMAL, A, B};
	/** Contructor */
	FilterCompressor();
	/** Copy Contructor */
	FilterCompressor(const FilterCompressor&);
	/** Do nothing */
	void Init();
	/** Tune the Filter 
	\param conf DynArray of int,
	\arg \c 0 : attack * 10.;
	\arg \c 1 : delay * 10.;
	\arg \c 2 : soft curve (or not)
	\arg \c 3 : floor*100
	\arg \c 4 : ratio	
	\arg \c 5 : type	
	\arg \c 6 : bitrate;
	*/
	void Tune(DynArray<int>);


	Buffer& Preview(Buffer&);
	double *Preview(double*, int);

	Buffer& Execution(Buffer&);
	double *Execution(double*, int);
	string HowToTune();



	private:
	double grabLevel(double);
	double compress(double);
	double delay_effect(double);
	double get_t(double);

	uint borne; //distance du seuil pour calculer le soft knee
	float attack; //in ms
	float delay; //in ms
	short soft;  //0 => No, 1 => Quadratic Spline, 2 => Besier
	double floor; //when we start compression
	uint ratio; //Db loss
	float attack_elapsed; //time we have elapsed in attack
	float delay_elapsed;
	short type; //impulse response type;
	uint bitrate;

	double z0,z1,z2; //for interpolation	
	double cfloor, rfloor;
	double delay_factor;

};

}
#endif


